/*
演示可执行程序的“段（segment）”
编译方法：c++ -g -S segment_demo.cpp
查看生成的汇编代码：segment_demo.s
*/
#include <cmath>
#include <iostream>
#include <map>
#include <thread>
using namespace std;

int g_ii1[1] = {1};
int g_ui1[1]; // 没初始化
const int g_ci1 = 1;
static int g_si1 = 1;

int g_ii2[1] = {1}; // 特意交替定义
int g_ui2[1];
const int g_ci2 = 2;
static int g_si2 = 1;

map<void*, string> m;

void foo(int n) {
  static int s_i0 = 0;
  static int s_i1 = 1;
  static int s_u1;
  m[(void*)&n] = ".stack foo().n = " + to_string(n);
  m[(void*)&s_i0] = ".bss foo().s_i0 = " + to_string(s_i0);
  m[(void*)&s_i1] = ".data foo().s_i1 = " + to_string(s_i1);
  m[(void*)&s_u1] = ".bss foo().s_u1 = " + to_string(s_u1);
  ++s_i1;
  ++s_u1;
  if(n < 3) {
    foo(n + 1);
  }
}

int main() {
  int l_ai1;
  const int l_ci1 = 1;
  constexpr int l_ei1 = 1;
  static int s_li0 = 0; // 初值为0相当于默认初始化，bss段
  static int s_li1 = 1;
  static int s_ui1;
  int* piv1 = new int(1); // 动态分配的地址有对齐的负担。
  int* pia1 = new int[1];

  int l_ai2; // 特意交替定义
  const int l_ci2 = 2;
  constexpr int l_ei2 = 2;
  static int s_li2 = 2;
  static int s_ui2;
  int* piv2 = new int(2);
  int* pia2 = new int[2];
 
  m[(void*)&main] = ".code main()"; // 自定义函数
  m[(void*)foo] = ".code foo";
  m[(void*)&printf] = ".code printf()"; // C库函数
  m[(void*)&sinf] = ".code sinf()"; // 数学库
  m[(void*)&std::this_thread::get_id] = ".code std::this_thread::get_id()"; // 线程库
  m[(void*)&g_ii1] = ".data g_ii1";
  m[(void*)&g_ii2] = ".data g_ii2";
  m[(void*)&g_ui1] = ".bss g_ui1";
  m[(void*)&g_ui2] = ".bss g_ui2";
  m[(void*)&g_si1] = ".data g_si1";
  m[(void*)&g_si2] = ".data g_si2";
  m[(void*)&g_ci1] = ".const g_ci1";
  m[(void*)&g_ci2] = ".const g_ci2";
  m[(void*)&l_ai1] = ".stack l_ai1";
  m[(void*)&l_ci1] = ".stack l_ci1";
  m[(void*)&l_ei1] = ".stack l_ei1";
  m[(void*)&s_li0] = ".bss s_li0";
  m[(void*)&s_li1] = ".data s_li1";
  m[(void*)&s_ui1] = ".bss s_ui1";
  m[(void*)&l_ai2] = ".stack l_ai2";
  m[(void*)&l_ci2] = ".stack l_ci2";
  m[(void*)&l_ei2] = ".stack l_ei2";
  m[(void*)&s_li2] = ".data s_li2";
  m[(void*)&s_ui2] = ".bss s_ui2";
  m[(void*)piv1] = ".heap piv1";
  m[(void*)piv2] = ".heap piv2";
  m[(void*)pia1] = ".heap pia1";
  m[(void*)pia2] = ".heap pia2";
  foo(1);
  foo(1); // 再递归调用一轮，观察堆栈段的使用。
  for(auto& e : m) {
    cout << e.first << ": " << e.second << endl;
  }
}